#include <stdarg.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <resolv.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>

#include "../include/echo_client.h"

#define MAXBUF 1024
#define PORT 33000
//void PANIC(char *msg);
#define PANIC(msg) {printf("> %s\n",msg);exit(EXIT_FAILURE);}

int readline(int fd, void *str, int max_len);
int sendline(int fd, const void *str, size_t maxlen);

int main(int argc, char *argv[]) {
	int sockfd;
	char* ip;
	char *endptr;
	int port;
	char* buffer = malloc(sizeof(char) * MAXBUF);
	char *commande_request = ".request\n";

	/*---Make sure we have the right number of parameters
	 */

	if (argc == 3) {
		port = strtol(argv[2], &endptr, 0);
		ip = argv[1];
		if (*endptr) {
			fprintf(stderr, "ECHOSERV : Invalid port number\n");
			exit(EXIT_FAILURE);
		}
	} else if (argc < 3) {
		port = PORT;
		ip = "127.0.0.1";
	} else {
		fprintf(stderr, "ECHOSERV: Invalid arguments\n");
		exit(EXIT_FAILURE);
	}

	sockfd = create_conn(port, ip);

	fd_set readfs;

	/* send our name */

	while (1) {
		FD_ZERO(&readfs);

		/* add STDIN_FILENO */FD_SET(STDIN_FILENO, &readfs);

		/* add the socket */FD_SET(sockfd, &readfs);

		if (select(sockfd + 1, &readfs, NULL, NULL, NULL) == -1) {
			perror("select()");
			exit(errno);
		}

		/* something from standard input : i.e keyboard */
		if (FD_ISSET(STDIN_FILENO, &readfs)) {
			memset(buffer, 0, MAXBUF);
			buffer = fgets(buffer, MAXBUF, stdin);
			clean(buffer);

			if (sendline(sockfd, buffer, strlen(buffer)) < 0) {
				perror("Send");
				exit(EXIT_FAILURE);
			}
		} else if (FD_ISSET(sockfd, &readfs)) {
			memset(buffer, 0, MAXBUF);
			int n = readline(sockfd, buffer, MAXBUF - 1);
			/* server down */
			if (n == 0) {
				printf("Server disconnected !\n");
				break;
			}
			if (!strcmp(buffer, commande_request)) {
				int fileSock;
				int port = 0;

				create_socket("127.0.0.1", &port, &fileSock);
				port = htons(port);
				fprintf(stdout, "Port : %d\n", port);

				if (write(sockfd, &port, sizeof(port)) < 0) {
					perror("write");
					exit (EXIT_FAILURE);
				}

/*				if(sendline(sockfd, buffer, sizeof(port)) < 0){
					perror("Send");
					exit(EXIT_FAILURE);
				}*/
			}
			else {
				puts(buffer);
			}
		}
	}
	return EXIT_SUCCESS;
}

int readline(int fd, void *str, int max_len) {
	int n, rc;
	char c;
	char* buffer;

	buffer = str;
	for (n = 1; n < max_len; n++) {
		if ((rc = read(fd, &c, 1)) == 1) {
			*buffer++ = c;
			if (c == '\n')
				break;
		} else {
			if (rc == 0) {
				if (n == 1)
					return 0;
				else
					break;
			}
			if (rc == -1) {
				if (errno == EINTR)
					continue;
				else
					return -1;
			}
		}
	}
	*buffer = '\0';
	return n;
}

int sendline(int fd, const void *str, size_t maxlen) {
	int nleft; //caractères restant à écrire
	int nwritten; // caractères déjà écrits

	const char* buffer;

	buffer = str;
	nleft = maxlen;
	while (nleft > 0) {
		if ((nwritten = write(fd, buffer, nleft)) < 0) {
			if (errno == EINTR)
				nwritten = 0;
			else
				return -1;
		}
		nleft -= nwritten;
		buffer += nwritten;
	}
	return maxlen;
}

void clean(char *buffer) {
	char* p = NULL;
	p = strchr(buffer, '\n');
	if (p == NULL) {
		int c;
		while ((c = getchar()) != '\n' && c != EOF) {
		}
	}
}
